using System.Collections.Concurrent;
using CMS.EFCore;
using Microsoft.EntityFrameworkCore;

namespace CMS.Common;

public static class ArticleHitCounter {
    private static readonly ConcurrentQueue<int> ArticleIdQueue = new();
    private static readonly CancellationTokenSource CancellationTokenSource = new();
    private static readonly int BatchSize = 100;
    private static readonly TimeSpan FlushInterval = TimeSpan.FromSeconds(10);

    static ArticleHitCounter() {
        StartProcessingQueue();
    }
    public static void HitsAdd(int articleId) {
        ArticleIdQueue.Enqueue(articleId);
        Console.WriteLine(articleId + "入队");
    }

    private static void StartProcessingQueue() {
        Task.Run(async () => {
            while (!CancellationTokenSource.Token.IsCancellationRequested) {
                await ProcessQueue();
                await Task.Delay(FlushInterval, CancellationTokenSource.Token);
            }
        }, CancellationTokenSource.Token);
    }

    // 处理队列中的文章 ID
    private static async Task ProcessQueue() {
        var articleIdCounts = new ConcurrentDictionary<int, int>();
        int processedCount = 0;

        while (processedCount < BatchSize && ArticleIdQueue.TryDequeue(out int articleId)) {
            articleIdCounts.AddOrUpdate(articleId, 1, (key, oldValue) => oldValue + 1);
            processedCount++;
        }
        
        if (articleIdCounts.Count > 0) {
            var myDbContext = ServiceProvider.GetService<MyDbContext>();
            foreach (var pair in articleIdCounts) {
                var article = await myDbContext.Articles.Where(a => a.Id == pair.Key).FirstOrDefaultAsync();
                if (article != null) {
                    article.Hits += pair.Value;
                }
            }

            await myDbContext.SaveChangesAsync();
        }
    }

    public static void StopProcessing() {
        CancellationTokenSource.Cancel();
        ProcessQueue().Wait();
    }
}